package com.yunke.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yunke.common.result.YunkeResult;
import com.yunke.entity.dto.YunkeCommunityDto;
import com.yunke.entity.vo.YunkeCommunityMemberVo;
import com.yunke.entity.vo.YunkeCommunityPostVo;
import com.yunke.entity.vo.YunkeCommunityVo;
import com.yunke.service.YunkeCommunityService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;

/**
 * 社群管理控制器
 * 
 * @author yunke
 * @since 1.0.0
 */
@Slf4j
@RestController
@RequestMapping("/api/community")
@RequiredArgsConstructor
@Tag(name = "社群管理", description = "社群管理相关接口")
public class YunkeCommunityController {

    private final YunkeCommunityService communityService;

    @PostMapping("/create")
    @SaCheckLogin
    @Operation(summary = "创建社群", description = "用户创建社群")
    public YunkeResult<Long> createCommunity(@Validated @RequestBody YunkeCommunityDto dto) {
        Long userId = StpUtil.getLoginIdAsLong();
        Long communityId = communityService.createCommunity(dto, userId);
        return YunkeResult.success("社群创建成功", communityId);
    }

    @PutMapping("/update")
    @SaCheckLogin
    @Operation(summary = "更新社群信息", description = "更新社群基本信息")
    public YunkeResult<Boolean> updateCommunity(@Validated @RequestBody YunkeCommunityDto dto) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.updateCommunity(dto, userId);
        return YunkeResult.success("社群信息更新成功", result);
    }

    @DeleteMapping("/delete/{communityId}")
    @SaCheckLogin
    @Operation(summary = "删除社群", description = "删除社群（群主权限）")
    public YunkeResult<Boolean> deleteCommunity(@Parameter(description = "社群ID") @PathVariable Long communityId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.deleteCommunity(communityId, userId);
        return YunkeResult.success("社群删除成功", result);
    }

    @GetMapping("/detail/{communityId}")
    @Operation(summary = "获取社群详情", description = "获取社群详细信息")
    public YunkeResult<YunkeCommunityVo> getCommunityDetail(@Parameter(description = "社群ID") @PathVariable Long communityId) {
        Long userId = StpUtil.getLoginIdAsLong();
        YunkeCommunityVo community = communityService.getCommunityDetail(communityId, userId);
        return YunkeResult.success(community);
    }

    @GetMapping("/page")
    @Operation(summary = "分页查询社群列表", description = "条件分页查询社群")
    public YunkeResult<Page<YunkeCommunityVo>> getCommunityPage(
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "关键词") @RequestParam(required = false) String keyword,
            @Parameter(description = "社群类型") @RequestParam(required = false) Integer communityType,
            @Parameter(description = "分类ID") @RequestParam(required = false) Long categoryId,
            @Parameter(description = "地区") @RequestParam(required = false) String region,
            @Parameter(description = "经度") @RequestParam(required = false) BigDecimal longitude,
            @Parameter(description = "纬度") @RequestParam(required = false) BigDecimal latitude,
            @Parameter(description = "距离范围(米)") @RequestParam(defaultValue = "10000") Integer distance) {
        Long userId = StpUtil.getLoginIdAsLong();
        Page<YunkeCommunityVo> page = communityService.getCommunityPage(current, size, keyword, 
                communityType, categoryId, region, longitude, latitude, distance, userId);
        return YunkeResult.success(page);
    }

    @GetMapping("/recommend")
    @Operation(summary = "获取推荐社群", description = "获取推荐社群列表")
    public YunkeResult<List<YunkeCommunityVo>> getRecommendCommunities(
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "10") Integer limit) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.getRecommendCommunities(userId, limit);
        return YunkeResult.success(communities);
    }

    @GetMapping("/hot")
    @Operation(summary = "获取热门社群", description = "获取热门社群列表")
    public YunkeResult<List<YunkeCommunityVo>> getHotCommunities(
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "10") Integer limit) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.getHotCommunities(userId, limit);
        return YunkeResult.success(communities);
    }

    @GetMapping("/nearby")
    @Operation(summary = "获取附近社群", description = "获取附近社群列表")
    public YunkeResult<List<YunkeCommunityVo>> getNearbyCommunities(
            @Parameter(description = "经度", required = true) @RequestParam BigDecimal longitude,
            @Parameter(description = "纬度", required = true) @RequestParam BigDecimal latitude,
            @Parameter(description = "距离范围(米)") @RequestParam(defaultValue = "5000") Integer distance,
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "20") Integer limit) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.getNearbyCommunities(longitude, latitude, distance, userId, limit);
        return YunkeResult.success(communities);
    }

    @GetMapping("/category/{categoryId}")
    @Operation(summary = "按分类获取社群", description = "根据分类获取社群列表")
    public YunkeResult<List<YunkeCommunityVo>> getCommunitiesByCategory(
            @Parameter(description = "分类ID") @PathVariable Long categoryId,
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "20") Integer limit) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.getCommunitiesByCategory(categoryId, userId, limit);
        return YunkeResult.success(communities);
    }

    @GetMapping("/search")
    @Operation(summary = "搜索社群", description = "关键词搜索社群")
    public YunkeResult<List<YunkeCommunityVo>> searchCommunities(
            @Parameter(description = "搜索关键词", required = true) @RequestParam String keyword,
            @Parameter(description = "数量限制") @RequestParam(defaultValue = "20") Integer limit) {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.searchCommunities(keyword, userId, limit);
        return YunkeResult.success(communities);
    }

    @PostMapping("/join/{communityId}")
    @SaCheckLogin
    @Operation(summary = "加入社群", description = "申请加入社群")
    public YunkeResult<Boolean> joinCommunity(
            @Parameter(description = "社群ID") @PathVariable Long communityId,
            @Parameter(description = "申请理由") @RequestParam(required = false) String reason) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.joinCommunity(communityId, userId, reason);
        return YunkeResult.success("加入申请已提交", result);
    }

    @PostMapping("/leave/{communityId}")
    @SaCheckLogin
    @Operation(summary = "退出社群", description = "退出社群")
    public YunkeResult<Boolean> leaveCommunity(@Parameter(description = "社群ID") @PathVariable Long communityId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.leaveCommunity(communityId, userId);
        return YunkeResult.success("已退出社群", result);
    }

    @PostMapping("/invite")
    @SaCheckLogin
    @Operation(summary = "邀请用户加入", description = "邀请用户加入社群")
    public YunkeResult<Boolean> inviteUser(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "被邀请用户ID", required = true) @RequestParam Long inviteUserId,
            @Parameter(description = "邀请消息") @RequestParam(required = false) String message) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.inviteUserToCommunity(communityId, userId, inviteUserId, message);
        return YunkeResult.success("邀请已发送", result);
    }

    @PostMapping("/remove-member")
    @SaCheckLogin
    @Operation(summary = "踢出成员", description = "踢出社群成员")
    public YunkeResult<Boolean> removeMember(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "成员ID", required = true) @RequestParam Long memberId,
            @Parameter(description = "踢出理由") @RequestParam(required = false) String reason) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.removeMemberFromCommunity(communityId, userId, memberId, reason);
        return YunkeResult.success("成员已被踢出", result);
    }

    @PostMapping("/set-admin")
    @SaCheckLogin
    @Operation(summary = "设为管理员", description = "设置成员为管理员")
    public YunkeResult<Boolean> setMemberAsAdmin(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "成员ID", required = true) @RequestParam Long memberId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.setMemberAsAdmin(communityId, userId, memberId);
        return YunkeResult.success("已设为管理员", result);
    }

    @PostMapping("/remove-admin")
    @SaCheckLogin
    @Operation(summary = "取消管理员", description = "取消成员管理员权限")
    public YunkeResult<Boolean> removeMemberAsAdmin(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "成员ID", required = true) @RequestParam Long memberId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.removeMemberAsAdmin(communityId, userId, memberId);
        return YunkeResult.success("已取消管理员权限", result);
    }

    @PostMapping("/mute-member")
    @SaCheckLogin
    @Operation(summary = "禁言成员", description = "禁言社群成员")
    public YunkeResult<Boolean> muteMember(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "成员ID", required = true) @RequestParam Long memberId,
            @Parameter(description = "禁言结束时间", required = true) @RequestParam Long muteEndTime,
            @Parameter(description = "禁言理由") @RequestParam(required = false) String reason) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.muteMember(communityId, userId, memberId, muteEndTime, reason);
        return YunkeResult.success("成员已被禁言", result);
    }

    @PostMapping("/unmute-member")
    @SaCheckLogin
    @Operation(summary = "解除禁言", description = "解除成员禁言")
    public YunkeResult<Boolean> unmuteMember(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "成员ID", required = true) @RequestParam Long memberId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.unmuteMember(communityId, userId, memberId);
        return YunkeResult.success("已解除禁言", result);
    }

    @PutMapping("/announcement")
    @SaCheckLogin
    @Operation(summary = "更新公告", description = "更新社群公告")
    public YunkeResult<Boolean> updateAnnouncement(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "公告内容", required = true) @RequestParam String announcement) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.updateCommunityAnnouncement(communityId, userId, announcement);
        return YunkeResult.success("公告更新成功", result);
    }

    @PutMapping("/rules")
    @SaCheckLogin
    @Operation(summary = "更新规则", description = "更新社群规则")
    public YunkeResult<Boolean> updateRules(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "规则内容", required = true) @RequestParam String rules) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.updateCommunityRules(communityId, userId, rules);
        return YunkeResult.success("规则更新成功", result);
    }

    @GetMapping("/members/{communityId}")
    @Operation(summary = "获取成员列表", description = "分页获取社群成员列表")
    public YunkeResult<Page<YunkeCommunityMemberVo>> getCommunityMembers(
            @Parameter(description = "社群ID") @PathVariable Long communityId,
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "20") Integer size,
            @Parameter(description = "成员角色筛选") @RequestParam(required = false) Integer memberRole,
            @Parameter(description = "搜索关键词") @RequestParam(required = false) String keyword) {
        Long userId = StpUtil.getLoginIdAsLong();
        Page<YunkeCommunityMemberVo> page = communityService.getCommunityMembers(communityId, current, size, memberRole, keyword, userId);
        return YunkeResult.success(page);
    }

    @GetMapping("/posts/{communityId}")
    @Operation(summary = "获取社群动态", description = "分页获取社群动态列表")
    public YunkeResult<Page<YunkeCommunityPostVo>> getCommunityPosts(
            @Parameter(description = "社群ID") @PathVariable Long communityId,
            @Parameter(description = "当前页") @RequestParam(defaultValue = "1") Integer current,
            @Parameter(description = "页大小") @RequestParam(defaultValue = "10") Integer size,
            @Parameter(description = "动态类型") @RequestParam(required = false) Integer postType,
            @Parameter(description = "只看置顶") @RequestParam(required = false) Boolean isTop,
            @Parameter(description = "只看精华") @RequestParam(required = false) Boolean isEssence) {
        Long userId = StpUtil.getLoginIdAsLong();
        Page<YunkeCommunityPostVo> page = communityService.getCommunityPosts(communityId, current, size, postType, isTop, isEssence, userId);
        return YunkeResult.success(page);
    }

    @GetMapping("/my/created")
    @SaCheckLogin
    @Operation(summary = "我创建的社群", description = "获取当前用户创建的社群列表")
    public YunkeResult<List<YunkeCommunityVo>> getMyCreatedCommunities() {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.getUserCreatedCommunities(userId);
        return YunkeResult.success(communities);
    }

    @GetMapping("/my/joined")
    @SaCheckLogin
    @Operation(summary = "我加入的社群", description = "获取当前用户加入的社群列表")
    public YunkeResult<List<YunkeCommunityVo>> getMyJoinedCommunities() {
        Long userId = StpUtil.getLoginIdAsLong();
        List<YunkeCommunityVo> communities = communityService.getUserJoinedCommunities(userId);
        return YunkeResult.success(communities);
    }

    @PostMapping("/transfer-ownership")
    @SaCheckLogin
    @Operation(summary = "转让群主", description = "转让社群群主权限")
    public YunkeResult<Boolean> transferOwnership(
            @Parameter(description = "社群ID", required = true) @RequestParam Long communityId,
            @Parameter(description = "新群主ID", required = true) @RequestParam Long newOwnerId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.transferCommunityOwnership(communityId, userId, newOwnerId);
        return YunkeResult.success("群主权限转让成功", result);
    }

    @PostMapping("/dissolve/{communityId}")
    @SaCheckLogin
    @Operation(summary = "解散社群", description = "解散社群（群主权限）")
    public YunkeResult<Boolean> dissolveCommunity(@Parameter(description = "社群ID") @PathVariable Long communityId) {
        Long userId = StpUtil.getLoginIdAsLong();
        boolean result = communityService.dissolveCommunity(communityId, userId);
        return YunkeResult.success("社群已解散", result);
    }

    @GetMapping("/stats/{communityId}")
    @Operation(summary = "社群统计", description = "获取社群统计信息")
    public YunkeResult<YunkeCommunityVo> getCommunityStats(@Parameter(description = "社群ID") @PathVariable Long communityId) {
        YunkeCommunityVo stats = communityService.getCommunityStats(communityId);
        return YunkeResult.success(stats);
    }
} 